home *** CD-ROM | disk | FTP | other *** search
- /* cycle.c */
-
- /* Copyright (c) 1988 David J. Arendash, Inc. */
-
- /* This file contains general purpose routines for the handling of
- multiple timer requests useful in applications requiring things like
- color cycling. The actual color cycle routine I use is include here
- in a comment, as you may want to tailor it for your application.
-
- These routines rely on routines in timer.c, also by me.
-
- You may want to break this file up to library-ize these routines.
-
- Feel free to do anything you want with this stuff. I only ask that
- 1. Don't delete these comments
- 2. Follow this indentation and punctuation, as it is the least
- annoying and easiest to follow, all pinheads aside.
- */
-
- #include "exec/types.h"
- #include "exec/nodes.h"
- #include "exec/lists.h"
- #include "exec/memory.h"
- #include "exec/interrupts.h"
- #include "exec/ports.h"
- #include "exec/libraries.h"
- #include "exec/tasks.h"
- #include "exec/io.h"
- #include "exec/devices.h"
- #include "devices/timer.h"
- #include <stdio.h>
-
- /* 4 color cycles in most paint programs */
- #define CYCS 4
-
- /* used in test routine only */
- static char x[6] = {"0000",13};
-
- struct timeval cyc_time[CYCS];
- struct IOStdReq *cyc_msg[CYCS], *prototimer;
-
- /* keep track of the existance of timer(s) */
- char TimerOn = 0;
-
- extern struct IOStdReq *CreateTimer();
-
- /*
-
- This is used for testing
-
- main ()
- {
- SetCycleTime (3, 3000L);
- SetCycleTime (1, 1500L);
- SetCycleTime (0, 60L);
- SetCycleTime (3, 24L);
-
- if (!SetupCycles())
- exit (0);
-
- StartCycles ();
- while (PerformCycles());
- StopCycles();
- DestroyCycles();
- }
- */
-
- /* sets a timer period based on the (IFF) convention that 16384 = 1/60 sec and
- 273 = 1 sec.
- Does not start a timer */
-
- SetCycleTime (index, period)
- short index;
- long period;
- {
- long t;
-
- t = 273066667 / period;
- cyc_time[index].tv_secs = t / 1000000;
- cyc_time[index].tv_micro = t - (cyc_time[index].tv_secs * 1000000);
- }
-
- /* Perform one-time initialization for using timers and cycles */
- SetupCycles ()
- {
- short i;
-
- /* create a prototype timer so we can InitTimerDevice */
- prototimer = CreateTimer ();
- if (prototimer == NULL)
- return (0);
-
- if (!InitTimerDevice (prototimer, (long)UNIT_VBLANK))
- return (0);
-
- /* create timers for cycling based on the prototype timer */
- for (i=0; i < CYCS; i++)
- {
- cyc_msg[i] = CreateTimer();
- DupTimer (prototimer, cyc_msg[i]);
- }
- }
-
- /* start all timers to get the balls rolling */
- StartCycles()
- {
- short i;
-
- for (i=0; i < CYCS; i++)
- {
- QTimer_tv (cyc_msg[i], &cyc_time[i]);
- }
- TimerOn = 1;
- }
-
- /* Perform the action associated with the timers.
- Call as often as possible (like while waiting for a message). */
- PerformCycles ()
- {
- short i;
-
- if (!TimerOn)
- return (0);
-
- for (i=0; i < CYCS; i++)
- {
- /* timer ready? */
- if (CheckTimer (cyc_msg[i]))
- {
- /* call the actual "thing-to-do" */
- CycleRange(i);
- /* restart timer */
- QTimer_tv (cyc_msg[i], &cyc_time[i]);
- }
- }
- return (1);
- }
-
- /* stops all timers */
- StopCycles()
- {
- short i;
-
- for (i=0; i < CYCS; i++)
- {
- AbortTimer (cyc_msg[i]);
- }
- TimerOn = 0;
- }
-
- /* shut down all timer activity */
- DestroyCycles ()
- {
- short i;
-
- CloseDevice (prototimer);
- for (i=0; i < CYCS; i++)
- {
- DeleteTimer (cyc_msg[i]);
- }
- DeleteTimer (prototimer);
- }
-
- /* Do what you want based on the timer. This is a test routine. You
- Supply your own */
- CycleRange (i)
- short i;
- {
-
- x[4] = 13;
- x[5] = 0;
-
- if (x[i] == '0')
- x[i] = '1';
- else
- x[i] = '0';
-
- printf ("%s",x);
- fflush (stdout);
- }
-
- #ifdef DoingItMyWay
-
- /* These are the routines I use to perform color cycling.
- It assumes you have an array of shorts containing the color pallet (cmap)
- CRange is an IFF chunk and defined as follows:
- struct CRange
- {
- WORD pad1;
- WORD rate;
- WORD active;
- UBYTE low, high;
- };
-
- These routines assume (as Deluxe Paint does (in a non-standard way))
- that a cycle is on if the rate is greater than 24 (Hex) and the
- low color is different than the high color. Had they done it according
- to the IFF spec, active would be non-zero if the range is active.
-
- ShiftRange (vp, cmap, range)
- struct Viewport *vp;
- short *cmap;
- struct CRange *range;
- {
-
- short i,j;
- long tcol;
-
- i = range->high;
- j = range->low;
-
- /* 1 if cylcing low to high */
- /* 3 if cycling high to low (backward) */
- if (range->active == 1)
- {
- tcol = cmap[i];
- for (; i > j; i--)
- {
- cmap[i] = cmap[i-1];
- }
- cmap[j] = tcol;
- }
- else if (range->active == 3)
- {
- tcol = cmap[j];
- for (; j < i; j++)
- {
- cmap[j] = cmap[j+1];
- }
- cmap[i] = tcol;
- }
- LoadRGB4 (vp, cmap, (long)range->high);
- }
-
- CycleRange (index)
- short index;
- {
- /* only cycle if range is active (according to DPaint) */
- if (ColorRange[index].rate < 0x25)
- return (0);
- if (ColorRange[index].low == ColorRange[index].high)
- return (0);
- ShiftRange (&AppScreen->ViewPort, &new_cmap, &ColorRange[index]);
-
- }
- #endif
-